{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "65ff977a-55a8-4044-9fcc-04cdb9645e11",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "6eddf564-9b30-4fef-885d-979081f4d015",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.ensemble import IsolationForest  # 异常检测\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 1. 模拟原始数据集（基于实际业务指标）\n",
    "data = {\n",
    "    \"timestamp\": pd.date_range(\"2025-07-10 00:00:00\", periods=3600, freq=\"s\"),\n",
    "    \"vehicle_id\": np.random.choice([\"V001\", \"V002\", \"V003\"], 3600),\n",
    "    \"speed\": np.concatenate([np.random.normal(60, 5, 3000), np.random.normal(100, 10, 600)]),  # 混入超速数据\n",
    "    \"acceleration\": np.random.uniform(-3.5, 3.5, 3600),  # 急加速/急刹车\n",
    "    \"brake_status\": np.random.choice([0, 1], 3600, p=[0.85, 0.15]),  # 制动信号\n",
    "    \"engine_rpm\": np.random.randint(800, 3000, 3600),\n",
    "    \"gps_lat\": np.cumsum(np.random.normal(0, 0.001, 3600)),  # 模拟行驶轨迹\n",
    "    \"gps_lon\": np.cumsum(np.random.normal(0, 0.001, 3600))\n",
    "}\n",
    "df = pd.DataFrame(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "f4bb4e9c-cafa-4080-9dc3-27fefd66616f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>timestamp</th>\n",
       "      <th>vehicle_id</th>\n",
       "      <th>speed</th>\n",
       "      <th>acceleration</th>\n",
       "      <th>brake_status</th>\n",
       "      <th>engine_rpm</th>\n",
       "      <th>gps_lat</th>\n",
       "      <th>gps_lon</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2025-07-10 00:00:00</td>\n",
       "      <td>V002</td>\n",
       "      <td>58.856119</td>\n",
       "      <td>3.146908</td>\n",
       "      <td>1</td>\n",
       "      <td>1308</td>\n",
       "      <td>0.000541</td>\n",
       "      <td>-0.000555</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2025-07-10 00:00:01</td>\n",
       "      <td>V003</td>\n",
       "      <td>65.712781</td>\n",
       "      <td>2.753540</td>\n",
       "      <td>0</td>\n",
       "      <td>1707</td>\n",
       "      <td>-0.000139</td>\n",
       "      <td>-0.003437</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2025-07-10 00:00:02</td>\n",
       "      <td>V002</td>\n",
       "      <td>64.222970</td>\n",
       "      <td>0.777131</td>\n",
       "      <td>0</td>\n",
       "      <td>1244</td>\n",
       "      <td>-0.000426</td>\n",
       "      <td>-0.004577</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2025-07-10 00:00:03</td>\n",
       "      <td>V003</td>\n",
       "      <td>58.980653</td>\n",
       "      <td>1.428297</td>\n",
       "      <td>0</td>\n",
       "      <td>2085</td>\n",
       "      <td>0.000367</td>\n",
       "      <td>-0.003236</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2025-07-10 00:00:04</td>\n",
       "      <td>V001</td>\n",
       "      <td>63.602957</td>\n",
       "      <td>-3.198077</td>\n",
       "      <td>0</td>\n",
       "      <td>2556</td>\n",
       "      <td>0.001718</td>\n",
       "      <td>-0.003585</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3595</th>\n",
       "      <td>2025-07-10 00:59:55</td>\n",
       "      <td>V002</td>\n",
       "      <td>103.228674</td>\n",
       "      <td>-1.647081</td>\n",
       "      <td>0</td>\n",
       "      <td>1842</td>\n",
       "      <td>0.116465</td>\n",
       "      <td>-0.033406</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3596</th>\n",
       "      <td>2025-07-10 00:59:56</td>\n",
       "      <td>V003</td>\n",
       "      <td>98.410744</td>\n",
       "      <td>-3.273627</td>\n",
       "      <td>0</td>\n",
       "      <td>2315</td>\n",
       "      <td>0.118131</td>\n",
       "      <td>-0.034076</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3597</th>\n",
       "      <td>2025-07-10 00:59:57</td>\n",
       "      <td>V001</td>\n",
       "      <td>110.389438</td>\n",
       "      <td>2.344508</td>\n",
       "      <td>0</td>\n",
       "      <td>1439</td>\n",
       "      <td>0.117909</td>\n",
       "      <td>-0.034407</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3598</th>\n",
       "      <td>2025-07-10 00:59:58</td>\n",
       "      <td>V001</td>\n",
       "      <td>102.598030</td>\n",
       "      <td>1.328957</td>\n",
       "      <td>0</td>\n",
       "      <td>1656</td>\n",
       "      <td>0.117997</td>\n",
       "      <td>-0.034493</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3599</th>\n",
       "      <td>2025-07-10 00:59:59</td>\n",
       "      <td>V002</td>\n",
       "      <td>97.779839</td>\n",
       "      <td>2.946465</td>\n",
       "      <td>0</td>\n",
       "      <td>2661</td>\n",
       "      <td>0.119227</td>\n",
       "      <td>-0.035547</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>3600 rows × 8 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "               timestamp vehicle_id       speed  acceleration  brake_status  \\\n",
       "0    2025-07-10 00:00:00       V002   58.856119      3.146908             1   \n",
       "1    2025-07-10 00:00:01       V003   65.712781      2.753540             0   \n",
       "2    2025-07-10 00:00:02       V002   64.222970      0.777131             0   \n",
       "3    2025-07-10 00:00:03       V003   58.980653      1.428297             0   \n",
       "4    2025-07-10 00:00:04       V001   63.602957     -3.198077             0   \n",
       "...                  ...        ...         ...           ...           ...   \n",
       "3595 2025-07-10 00:59:55       V002  103.228674     -1.647081             0   \n",
       "3596 2025-07-10 00:59:56       V003   98.410744     -3.273627             0   \n",
       "3597 2025-07-10 00:59:57       V001  110.389438      2.344508             0   \n",
       "3598 2025-07-10 00:59:58       V001  102.598030      1.328957             0   \n",
       "3599 2025-07-10 00:59:59       V002   97.779839      2.946465             0   \n",
       "\n",
       "      engine_rpm   gps_lat   gps_lon  \n",
       "0           1308  0.000541 -0.000555  \n",
       "1           1707 -0.000139 -0.003437  \n",
       "2           1244 -0.000426 -0.004577  \n",
       "3           2085  0.000367 -0.003236  \n",
       "4           2556  0.001718 -0.003585  \n",
       "...          ...       ...       ...  \n",
       "3595        1842  0.116465 -0.033406  \n",
       "3596        2315  0.118131 -0.034076  \n",
       "3597        1439  0.117909 -0.034407  \n",
       "3598        1656  0.117997 -0.034493  \n",
       "3599        2661  0.119227 -0.035547  \n",
       "\n",
       "[3600 rows x 8 columns]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "7200bd22-b478-4d53-a096-4ce8940d2610",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_207936/1824341336.py:5: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  df[\"hour\"] = df[\"timestamp\"].dt.hour\n",
      "/tmp/ipykernel_207936/1824341336.py:7: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  df[\"is_night\"] = df[\"hour\"].apply(lambda x: 1 if x in [22, 23, 0, 1, 2, 3, 4, 5] else 0)\n",
      "/tmp/ipykernel_207936/1824341336.py:11: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  df[\"hard_accel\"] = np.where(df[\"acceleration\"] > 2.5, 1, 0)\n",
      "/tmp/ipykernel_207936/1824341336.py:13: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  df[\"hard_brake\"] = np.where(df[\"acceleration\"] < -2.5, 1, 0)\n",
      "/tmp/ipykernel_207936/1824341336.py:15: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  df[\"overspeed\"] = np.where(df[\"speed\"] > 100, 1, 0)\n"
     ]
    }
   ],
   "source": [
    "# 2. 数据预处理（Pandas核心操作）\n",
    "# 异常值清洗：速度>120km/h或加速度绝对值>3.5 m/s²视为异常\n",
    "df = df[(df[\"speed\"] <= 120) & (df[\"acceleration\"].abs() <= 3.5)]\n",
    "# 时间序列特征：提取小时与分钟\n",
    "df[\"hour\"] = df[\"timestamp\"].dt.hour\n",
    "# 标记夜间驾驶（疲劳驾驶风险）\n",
    "df[\"is_night\"] = df[\"hour\"].apply(lambda x: 1 if x in [22, 23, 0, 1, 2, 3, 4, 5] else 0)\n",
    "\n",
    "# 3. 驾驶行为特征工程（Numpy数值计算）\n",
    "# 急加速：加速度>2.5 m/s²\n",
    "df[\"hard_accel\"] = np.where(df[\"acceleration\"] > 2.5, 1, 0)\n",
    "# 急刹车：加速度<-2.5 m/s²\n",
    "df[\"hard_brake\"] = np.where(df[\"acceleration\"] < -2.5, 1, 0)\n",
    "# 超速：速度>100km/h\n",
    "df[\"overspeed\"] = np.where(df[\"speed\"] > 100, 1, 0)\n",
    "\n",
    "# 4. 聚合驾驶员风险评分（按车辆分组）\n",
    "driver_risk = df.groupby(\"vehicle_id\").agg(\n",
    "    total_events=(\"hard_accel\", \"count\"),  # 总事件数\n",
    "    risk_ratio=(\"hard_accel\", lambda x: (x.sum() + df.loc[x.index, \"hard_brake\"].sum() + df.loc[x.index, \"overspeed\"].sum()) / len(x))\n",
    ").reset_index()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f8a29e6-d14a-4487-bd02-8f2dec2f670e",
   "metadata": {},
   "outputs": [],
   "source": [
    "driver_risk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8248e6b8-77e3-41f3-a41a-49c2a54180cf",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b0c2f561-340d-4c5c-ad84-053d5dc9ff1f",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0282e142-6554-4b0b-b438-dc39ad0e2359",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
